package com.tgr.shortLink.admin.service.impl;


import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tgr.shortLink.admin.common.context.BaseContext;
import com.tgr.shortLink.admin.common.convention.result.Result;
import com.tgr.shortLink.admin.dao.entity.GroupDO;
import com.tgr.shortLink.admin.dao.mapper.GroupMapper;
import com.tgr.shortLink.admin.dto.req.GroupSortReqDTO;
import com.tgr.shortLink.admin.dto.req.GroupUpdateReqDTO;
import com.tgr.shortLink.admin.dto.resp.GroupListRespDTO;
import com.tgr.shortLink.admin.remote.ShortLinkActualRemoteService;
import com.tgr.shortLink.admin.remote.ShortLinkRemoteService;
import com.tgr.shortLink.admin.remote.dto.resp.LinkGroupQueryRespDTO;
import com.tgr.shortLink.admin.service.GroupService;
import com.tgr.shortLink.admin.toolkit.RandomGenerator;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 描述：短链接服务接口实现层
 * 作者：小陶不慌张
 * 文件：GroupServiceImpl
 * 日期：2024/1/14 0:22
 */

@Service
@RequiredArgsConstructor
public class GroupServiceImpl extends ServiceImpl<GroupMapper, GroupDO> implements GroupService {

    ShortLinkRemoteService shortLinkRemoteService = new ShortLinkRemoteService(){
    };
    private final ShortLinkActualRemoteService shortLinkActualRemoteService;




    /**
     * 短链接新增分组
     * @param groupName 新增分组的名称
     */
    @Override
    public void saveGroup(String groupName) {
        saveGroup(BaseContext.getUsername(), groupName);
    }

    /**
     * 短链接新增分组
     * @param userName 当前用户名
     * @param groupName 分组名称
     */
    @Override
    public void saveGroup(String userName, String groupName) {
        String gid;
        do{
            gid = RandomGenerator.generateRandom();
        }while (!hasGid(userName,gid));
        GroupDO groupDO =GroupDO.builder()
                .gid(gid)
                .sortOrder(0)
                .username(userName)
                .name(groupName)
                .build();
        baseMapper.insert(groupDO);
    }

    /**
     * 判断数据库中是否已有该分组
     * @param gid 分组标识
     * @return 如果为空则返回ture
     */
    @Override
    public boolean hasGid(String userName,String gid) {

        LambdaQueryWrapper<GroupDO> wrapper = Wrappers.lambdaQuery(GroupDO.class)
                .eq(GroupDO::getGid,gid)
                //通过拦截器获取当前用户名
                .eq(GroupDO::getUsername, Optional.ofNullable(userName).orElse(BaseContext.getUsername()));
        GroupDO hasGidGroup = baseMapper.selectOne(wrapper);
        return hasGidGroup == null;
    }

    /**
     * 短链接分组查询
     * @return 查询出的List列表
     */
    @Override
    public List<GroupListRespDTO> listGroup() {

        LambdaQueryWrapper<GroupDO> wrapper = Wrappers.lambdaQuery(GroupDO.class)
                .eq(GroupDO::getDelFlag,0)
                .eq(GroupDO::getUsername,BaseContext.getUsername())
                .orderByDesc(GroupDO::getSortOrder,GroupDO::getUpdateTime);
        List<GroupDO> groupDOList=baseMapper.selectList(wrapper);
        Result<List<LinkGroupQueryRespDTO>> listResult = shortLinkActualRemoteService
                .linkCountQuery(groupDOList.stream().map(GroupDO::getGid).toList());
        List<GroupListRespDTO> linkGroupQueryRespDTOList = BeanUtil.copyToList(groupDOList,GroupListRespDTO.class);
        linkGroupQueryRespDTOList.forEach(each->{
            Optional<LinkGroupQueryRespDTO> first = listResult.getData().stream()
                    .filter(item-> Objects.equals(item.getGid(),each.getGid()))
                    .findFirst();
            first.ifPresent(item->each.setLinkCount(first.get().getLinkCount()));
        });
        return linkGroupQueryRespDTOList;
    }

    /**
     * 短链接分组更新功能
     * @param requestParam 更新入参
     */
    @Override
    public void updateGroup(GroupUpdateReqDTO requestParam) {
        LambdaQueryWrapper<GroupDO> updateWrapper = Wrappers.lambdaQuery(GroupDO.class)
                .eq(GroupDO::getDelFlag,0)
                .eq(GroupDO::getUsername,BaseContext.getUsername())
                .eq(GroupDO::getGid,requestParam.getGid());
        GroupDO groupDO = new GroupDO();
        groupDO.setName(requestParam.getName());
        baseMapper.update(groupDO,updateWrapper);

    }

    /**
     * 短链接分组删除功能
     * @param gid 分组标识
     */
    @Override
    public void deleteGroup(String gid) {
        //通过软删除实现分组删除功能
        LambdaQueryWrapper<GroupDO> deleteWrapper= Wrappers.lambdaQuery(GroupDO.class)
                .eq(GroupDO::getDelFlag,0)
                .eq(GroupDO::getUsername,BaseContext.getUsername())
                .eq(GroupDO::getGid,gid);
        GroupDO groupDO = new GroupDO();
        groupDO.setDelFlag(1);
        baseMapper.update(groupDO,deleteWrapper);
    }

    /**
     * 短链接分组排序
     * @param requestParam 短链接排序入参
     */
    @Override
    public void sortGroup(List<GroupSortReqDTO> requestParam) {
        //遍历每个数据并更新数据库中的sortOrder
        requestParam.forEach(each->{
            GroupDO groupDO=GroupDO.builder()
                    .gid(each.getGid())
                    .sortOrder(each.getSortOrder())
                    .build();
            LambdaQueryWrapper<GroupDO> sortWrapper= Wrappers.lambdaQuery(GroupDO.class)
                    .eq(GroupDO::getDelFlag,0)
                    .eq(GroupDO::getUsername,BaseContext.getUsername())
                    .eq(GroupDO::getGid,each.getGid());
            baseMapper.update(groupDO,sortWrapper);
        });
    }
}
